﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AdaptiveDeNet.Functions;
using AdaptiveDeNet.DifferentialEvolution;
using System.Diagnostics;
using AdaptiveDeNet.CSV;

namespace AdaptiveDeNet.Bechmark
{
    public class CEC14Benchmark
    {

        public void jdeBench()
        {
            List<double> records = new List<double>();
            List<double> elapsed = new List<double>();

            int fX = 100;

            for (int i = 1; i < 31; i++)
            {
                CEC14Suite suite = new CEC14Suite(i);

                for (int j = 0; j < 2; j++)
                {

                    Optimizer opt = new Optimizer(suite.Function);


                    Stopwatch sw = new Stopwatch();
                    sw.Start();



                    CEC14Result result = opt.jDE(suite.LowerBound,
                        suite.UpperBound, suite.MaxEvals, suite.Dim, suite.N, suite.MyEpps,
                        0.1, 0.1, suite.FESmultipliers, fX * i);
                    sw.Stop();

                    records.AddRange(result.Records);
                    elapsed.Add(sw.ElapsedMilliseconds);

                    if (result.Records.Count < 14)
                    {
                        int diff = 14 - result.Records.Count;

                        for (int k = 0; k < diff; k++)
                        {
                            records.Add(0);
                        }
                    }

                    suite.QueueRenew();

                }

                Console.WriteLine("func " + i + " completed");

                CSVwriter writer = new CSVwriter();

                String folder = "jDeParallel/";

                String fileName = "paraCEC14 func " + i;

                writer.WriteCEC14Results(folder + fileName, records, elapsed);

                records.Clear();
                elapsed.Clear();
            }
        }

        public void JADEBench()
        {
            List<double> records = new List<double>();
            List<double> elapsed = new List<double>();

            int fX = 100;

            for (int i = 1; i < 31; i++)
            {
                CEC14Suite suite = new CEC14Suite(i);

                for (int j = 0; j < 25; j++)
                {

                    Optimizer optimizer = new Optimizer(suite.Function);

                    Stopwatch sw = new Stopwatch();
                    sw.Start();

                    //TimeSpan begin = Process.GetCurrentProcess().TotalProcessorTime;

                    CEC14Result result = optimizer.JADE(suite.LowerBound,
                        suite.UpperBound, suite.MaxEvals, suite.Dim, suite.N, suite.MyEpps,0.05,0.1,
                        suite.FESmultipliers, fX * i, i);
                    sw.Stop();
                    //TimeSpan end = Process.GetCurrentProcess().TotalProcessorTime;

                    records.AddRange(result.Records);
                    elapsed.Add(sw.ElapsedMilliseconds);

                    if (result.Records.Count < 14)
                    {
                        int diff = 14 - result.Records.Count;

                        for (int k = 0; k < diff; k++)
                        {
                            records.Add(0);
                        }
                    }

                    suite.QueueRenew();

                }

                Console.WriteLine("func " + i + " completed");

                CSVwriter writer = new CSVwriter();

                String folder = "JADEseq/";

                String fileName = "paraCEC14 func " + i;

                writer.WriteCEC14Results(folder + fileName, records, elapsed);

                records.Clear();
                elapsed.Clear();
            }
        }

        public void JADEParallelBench()
        {
            List<double> records = new List<double>();
            List<double> elapsed = new List<double>();

            int fX = 100;

            for (int i = 1; i < 31; i++)
            {
                CEC14Suite suite = new CEC14Suite(i);

                for (int j = 0; j < 1; j++)
                {

                    AdaptiveDeNet.DifferentialEvolution.MultiThreaded.Optimizer optimizer = new AdaptiveDeNet.DifferentialEvolution.MultiThreaded.Optimizer(suite.Function);

                    Stopwatch sw = new Stopwatch();
                    sw.Start();

                    CEC14Result result = optimizer.JADE(suite.LowerBound,
                        suite.UpperBound, suite.MaxEvals, suite.Dim, suite.N, suite.MyEpps, 0.05, 0.1,
                        suite.FESmultipliers, fX * i, i);
                    sw.Stop();
                    //TimeSpan end = Process.GetCurrentProcess().TotalProcessorTime;

                    records.AddRange(result.Records);
                    elapsed.Add(sw.ElapsedMilliseconds);

                    if (result.Records.Count < 14)
                    {
                        int diff = 14 - result.Records.Count;

                        for (int k = 0; k < diff; k++)
                        {
                            records.Add(0);
                        }
                    }

                    suite.QueueRenew();

                }

                Console.WriteLine("func " + i + " completed");

                CSVwriter writer = new CSVwriter();

                String folder = "JADEpara/";

                String fileName = "paraCEC14 func " + i;

                writer.WriteCEC14Results(folder + fileName, records, elapsed);

                records.Clear();
                elapsed.Clear();
            }
        }

        public void jDEParallelBench()
        {
            List<double> records = new List<double>();
            List<double> elapsed = new List<double>();

            int fX = 100;

            for (int i = 1; i < 31; i++)
            {
                CEC14Suite suite = new CEC14Suite(i);

                for (int j = 0; j < 10; j++)
                {

                    AdaptiveDeNet.DifferentialEvolution.MultiThreaded.Optimizer opt = new AdaptiveDeNet.DifferentialEvolution.MultiThreaded.Optimizer(suite.Function);


                    Stopwatch sw = new Stopwatch();
                    sw.Start();



                    CEC14Result result = opt.jDE(suite.LowerBound,
                        suite.UpperBound, suite.MaxEvals, suite.Dim, suite.N, suite.MyEpps, suite.FESmultipliers,fX * i,i,
                        0.1, 0.1);
                    sw.Stop();

                    records.AddRange(result.Records);
                    elapsed.Add(sw.ElapsedMilliseconds);

                    if (result.Records.Count < 14)
                    {
                        int diff = 14 - result.Records.Count;

                        for (int k = 0; k < diff; k++)
                        {
                            records.Add(0);
                        }
                    }

                    suite.QueueRenew();

                }

                Console.WriteLine("func " + i + " completed");

                CSVwriter writer = new CSVwriter();

                String folder = "jDeSequential/";

                String fileName = "seqCEC14 func " + i;

                writer.WriteCEC14Results(folder + fileName, records, elapsed);

                records.Clear();
                elapsed.Clear();
            } 
        }

        public void deRand1BinBench(int funcNum)
        {
            List<double> records = new List<double>();
            List<double> elapsed = new List<double>();

            int fX = 100;

            for (int i = 1; i < 4; i++)
            {
                CEC14Suite suite = new CEC14Suite(i);

                for (int j = 0; j < 5; j++)
                {


                    Optimizer optimizer = new Optimizer(suite.Function);

                    Stopwatch sw = new Stopwatch();
                    sw.Start();

                    //TimeSpan begin = Process.GetCurrentProcess().TotalProcessorTime;

                    CEC14Result result = optimizer.de_rand_1_bin(0.5, 0.5, suite.LowerBound,
                        suite.UpperBound, suite.MaxEvals, suite.Dim, suite.N, suite.MyEpps,
                        suite.FESmultipliers, fX * i);
                    sw.Stop();
                    //TimeSpan end = Process.GetCurrentProcess().TotalProcessorTime;

                    records.AddRange(result.Records);
                    elapsed.Add(sw.ElapsedMilliseconds);

                    if (result.Records.Count < 14)
                    {
                        int diff = 14 - result.Records.Count;

                        for (int k = 0; k < diff; k++)
                        {
                            records.Add(0);
                        }
                    }

                    suite.QueueRenew();

                }

                Console.WriteLine("func " + i + " completed");

                CSVwriter writer = new CSVwriter();

                String folder = "derand1bin/";

                String fileName = "seqCEC14 func " + i;

                writer.WriteCEC14Results(folder + fileName, records, elapsed);

                records.Clear();
                elapsed.Clear();
            }


        }

        public void deRand1BinBenchParallel()
        {
            List<double> records = new List<double>();
            List<double> elapsed = new List<double>();

            int fX = 100;
            int funcNumber = 24;

            for (int i = 1; i < 5; i++)
            {

                CEC14Suite suite = new CEC14Suite(i);

                for (int j = 0; j < 15; j++)
                {

                    AdaptiveDeNet.DifferentialEvolution.MultiThreaded.Optimizer optimizer = new AdaptiveDeNet.DifferentialEvolution.MultiThreaded.Optimizer(suite.Function);

                    Stopwatch sw = new Stopwatch();
                    sw.Start();

                    CSV.CEC14Result result = optimizer.de_rand_1_bin(0.5, 0.5, suite.LowerBound,
                        suite.UpperBound, suite.MaxEvals, suite.Dim, suite.N, suite.MyEpps, suite.FESmultipliers, funcNumber * fX, funcNumber);
                    sw.Stop();
                    records.AddRange(result.Records);

                    if (result.Records.Count < 14)
                    {
                        int diff = 14 - result.Records.Count;

                        for (int k = 0; k < diff; k++)
                        {
                            records.Add(0);
                        }
                    }

                    elapsed.Add(sw.ElapsedMilliseconds);

                    suite.QueueRenew();
                }

                Console.WriteLine("func " + funcNumber + " completed");

                CSVwriter writer = new CSVwriter();

                String folder = "vysledky/";

                String fileName = "paraCEC14 func " + funcNumber + " threadCount " + i;

                writer.WriteCEC14Results(folder + fileName, records, elapsed);

                records.Clear();
                elapsed.Clear();
            }


        }

        public void b6e6rlBench()
        {
            List<double> records = new List<double>();
            List<double> elapsed = new List<double>();

            int fX = 100;

            for (int i = 1; i < 31; i++)
            {


                for (int j = 0; j < 10; j++)
                {
                    CEC14Suite suite = new CEC14Suite(i);

                    suite.MaxEvals = 300000;

                    Optimizer optimizer = new Optimizer(suite.Function);

                    Stopwatch sw = new Stopwatch();
                    sw.Start();

                    CEC14Result result = optimizer.de_b6e6rl(suite.LowerBound,
                        suite.UpperBound, suite.MaxEvals, suite.Dim, suite.N, suite.MyEpps, 2, 1 / 60.0, suite.FESmultipliers, i * fX);

                    sw.Stop();

                    records.AddRange(result.Records);
                    elapsed.Add(sw.ElapsedMilliseconds);

                    CEC14FuncImpl ptr = (CEC14FuncImpl)suite.Function;

                    ptr.Destroy();
                    suite = null;

                }

                Console.WriteLine("func: " + i + " completed");

                CSVwriter writer = new CSVwriter();

                String folder = "b6e6rl/";
                String fileName = "CEC14 func " + i;

                writer.WriteCEC14Results(folder + fileName, records, elapsed);

                records.Clear();
                elapsed.Clear();
            }


        }

        public void b6e6rlBenchParallel()
        {
            List<double> records = new List<double>();
            List<double> elapsed = new List<double>();

            int fX = 100;

            for (int i = 1; i < 31; i++)
            {


                for (int j = 0; j < 10; j++)
                {
                    CEC14Suite suite = new CEC14Suite(i);

                    suite.MaxEvals = 300000;

                    AdaptiveDeNet.DifferentialEvolution.MultiThreaded.Optimizer optimizer = new AdaptiveDeNet.DifferentialEvolution.MultiThreaded.Optimizer(suite.Function);


                    Stopwatch sw = new Stopwatch();
                    sw.Start();

                    CEC14Result result = optimizer.b6e6rl(suite.LowerBound, suite.UpperBound, suite.MaxEvals, suite.Dim, suite.N, suite.MyEpps, 2.0, 1 / 60.0, suite.FESmultipliers, i * fX, i);

                    sw.Stop();

                    records.AddRange(result.Records);
                    elapsed.Add(sw.ElapsedMilliseconds);

                    CEC14FuncImpl ptr = (CEC14FuncImpl)suite.Function;

                    ptr.Destroy();
                    suite = null;

                }

                Console.WriteLine("func: " + i + " completed");

                CSVwriter writer = new CSVwriter();

                String folder = "b6e6rlParallel/";
                String fileName = "CEC14 func " + i;

                writer.WriteCEC14Results(folder + fileName, records, elapsed);

                records.Clear();
                elapsed.Clear();
            }


        }
    }
}
